<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use stdClass;

class Common extends Model
{
    // 指定AND查询条件
    public $where = '';
    // 字段截取
    public $fields = '';
    // 排序
    public $orders = '';
    // 指定OR查询条件
    public $whereOr = '';
    // 指定Raw查询条件
    public $whereRaw = '';
    // 指定join查询 = '';
    public $asJoin = [];
    // 时间规则
    public $timeRules = 'Y-m-d H:i:s';
    // 错误信息
    protected $error = '';

    /**
     * 获取单个字段数据
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $whereOr
     * @return mixed|string
     */
    public function getField($where = '', $field = '',  $order = '', $whereOr = '')
    {
        $wheres = empty($where) ? $this->where : $where;
        $fields = empty($field) ? $this->fields : $field;
        $orders = empty($order) ? $this->orders : $order;
        $whereOrs = empty($whereOr) ? $this->whereOr : $whereOr;
        if (empty($wheres) && empty($whereOrs)) return '';
        if (empty($fields)) return '';
        $query = DB::table($this->table);
        // 主键查询
        if (is_numeric($wheres)){
            $query = $query->where($this->primaryKey, $wheres);
        }else{
            $query = $query->where($wheres);
        }
        // 存在order排序
        if (!empty($orders)){
            $order_list = explode(',', $orders);
            if (is_array($order_list)){
                foreach ($order_list as $key=>$val){
                    $orders_by = explode(' ', $val);
                    $query = $query->orderBy($orders_by['0'], $orders_by['1']);
                }
            }
        }
        return $query->value($fields);
    }

    /**
     * 获取单条数据
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $whereOr
     * @return array|null|Model
     */
    public function getFind($where = '', $field = '', $order = '', $whereOr = '')
    {
        if (empty($where)) return [];
        $query = $this->dataQuery($where, $field, $order, $whereOr);
        $data = $query->first();
        if (empty($data)) return [];
        return $data;
    }

    /**
     * 更新和修改操作
     * @param array $data
     * @param bool $auto_validate
     * @param bool $all
     * @param bool $getLastInsID
     * @return bool|string
     */
    public function operation($data = [] , $auto_validate = true, $all = false, $getLastInsID = false)
    {
        // $all 是否批量操作
        if ($auto_validate){
            if (is_array($auto_validate)){
                if (empty($auto_validate['rule'])){
                    $this->error = '验证失败';
                    return false;
                }
                // 是否批量验证
                if ($all){
                    foreach ($data as $key=>$val){
                        $validator = Validator::make($val, $auto_validate['rule'], $auto_validate['message']);
                        if (!$validator->fails()){
                            $this->error = $validator;
                            return false;
                        }
                    }
                }else{
                    $validator = Validator::make($data, $auto_validate['rule'], $auto_validate['message']);
                    if (!$validator->fails()){
                        $this->error = $validator;
                        return false;
                    }
                }
            }else{
                $class = '\\App\\Validator\\' . $this->getValidator();
                if (class_exists($class)) {
                    $validate = new $class();
                    // 是否批量验证
                    if ($all){
                        foreach ($data as $val){
                            if (!$validate->check($val)){
                                $this->error = $validate->getError();
                                return false;
                            }
                        }
                    }else{
                        if (!$validate->check($data)){
                            $this->error = $validate->getError();
                            return false;
                        }
                    }
                }else{
                    $this->error = '验证失败';
                    return false;
                }
            }
        }
        $query = DB::table($this->table);
        if ($all){
            $rows = $query->updateOrInsert($data);
        }else{
            if (empty($data[$this->primaryKey])){
                if ($getLastInsID == true){
                    return $query->insertGetId($data);
                }else{
                    $rows = $query->insert($data);
                }
            }else{
                $rows = $query->where($this->primaryKey, $data[$this->primaryKey])->update($data);
            }
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 状态操作设置
     * @param string $where
     * @param string $field
     * @param int $value
     * @param int $default
     * @return bool
     */
    public function status($where = '', $field = 'status', $value = 0 , $default = 1)
    {
        $wheres = empty($where) ? $this->where : $where;
        $fields = empty($field) ? $this->fields : $field;
        if (empty($wheres)) return false;
        // 批量修改
        if (is_array($wheres)){
            $keys = array_keys($wheres);
            if ($keys['0'] == 0){
                foreach ($wheres as $key=>$val){
                    $status = $this->getField($val, $fields);
                    $new_value = $status == $default ? $value : $default;
                    // 主键查询
                    if (is_numeric($val)){
                        $rows = DB::table($this->table)->where($this->primaryKey, $val)->update([$fields=>$new_value]);
                    }else{
                        $rows = DB::table($this->table)->where($val)->update([$fields=>$new_value]);
                    }
                    if (empty($rows)){
                        return false;
                    }
                }
            }else{
                $status = $this->getField($wheres, $fields);
                $new_value = $status == $default ? $value : $default;
                $rows = DB::table($this->table)->where($wheres)->update([$fields=>$new_value]);
            }
        }elseif (is_numeric($wheres)){
            // 主键查询
            $status = $this->getField($wheres, $fields);
            $new_value = $status == $default ? $value : $default;
            $rows = DB::table($this->table)->where($this->primaryKey, $wheres)->update([$fields=>$new_value]);
        }else{
            $status = $this->getField($wheres, $fields);
            $new_value = $status == $default ? $value : $default;
            $rows = DB::table($this->table)->where($wheres)->update([$fields=>$new_value]);
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 删除操作
     * @param string $where
     * @return bool
     */
    public function remove($where = '')
    {
        $wheres = empty($where) ? $this->where : $where;
        if (empty($wheres)) return false;
        // 批量删除
        if (is_array($wheres)){
            $keys = array_keys($wheres);
            if ($keys['0'] == 0){
                foreach ($wheres as $val){
                    // 主键查询
                    if (is_numeric($val)){
                        $rows = DB::table($this->table)->where($this->primaryKey, $val)->delete();
                    }else{
                        $rows = DB::table($this->table)->where($val)->delete();
                    }
                    if (empty($rows)){
                        return false;
                    }
                }
            }else{
                $rows = DB::table($this->table)->where($wheres)->delete();
            }
        }elseif (is_numeric($wheres)){
            // 主键查询
            $rows = DB::table($this->table)->where($this->primaryKey, $wheres)->delete();
        }else{
            $rows = DB::table($this->table)->where($wheres)->delete();
        }
        if (empty($rows)){
            return false;
        }
        return true;
    }

    /**
     * 检测是否存在
     * @param string $where
     * @return bool
     */
    public function getExists($where = '')
    {
        return $this->countExists($where);
    }

    /**
     * 数量统计
     * @param string $where
     * @return bool
     */
    public function getCount($where = '')
    {
        return $this->countExists($where, false);
    }

    public function countExists($where = '', $is_bool = true)
    {
        $wheres = empty($where) ? $this->where : $where;
        // 数据查询
        $query = Db::table($this->table);
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->primaryKey, $wheres);
            }else{
                if (is_array($wheres)){
                    // 获取是否是一维数组
                    if (count($wheres) != count($wheres, 1)){
                        foreach ($wheres as $val){
                            $query = $query->where($val['0'], $val['1'], $val['2']);
                        }
                    }else{
                        $query = $query->where($wheres);
                    }
                }
            }
        }
        $rows = $query->count();
        if ($is_bool){
            if (empty($rows)){
                return false;
            }
            return true;
        }
        return $rows;
    }

    /**
     * @param string|array $where
     * @param $field
     * @return float
     */
    public function getSum($where, $field)
    {
        $wheres = empty($where) ? $this->where : $where;
        if (empty($field)) return 0;
        // 数据查询
        $query = Db::table($this->table);
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->primaryKey, $wheres);
            }else{
                if (is_array($wheres)){
                    // 获取是否是一维数组
                    if (count($wheres) != count($wheres, 1)){
                        foreach ($wheres as $val){
                            $query = $query->where($val['0'], $val['1'], $val['2']);
                        }
                    }else{
                        $query = $query->where($wheres);
                    }
                }
            }
        }
        return $query->sum($field);
    }

    /**
     * 获取当前表字所有字段
     */
    public function getTableInfo()
    {
        $sql = "select COLUMN_NAME from information_schema.COLUMNS where table_name = '{$this->table}';";
        $data = DB::select($sql);
        return array_removal($data);
    }

    /**
     * 获取列表数据
     * @param string $where
     * @param string $limit
     * @param string $order
     * @param string $field
     * @param string $whereOr
     */
    public function getList($where = '', $limit = '', $order = '', $field = '', $whereOr = '')
    {
        $query = $this->dataQuery($where, $field, $order, $whereOr);
        if (!empty($limit)){
            if (is_numeric($limit)){
                $query = $query->limit($limit);
            }else{
                $limit_length = explode(',', $limit);
                $limit = intval($limit_length[0]);
                $length = intval($limit_length[1]);;
                $query = $query->offset($limit)->limit($length);
            }
        }
        return $query->get();
    }

    /**
     * 获取列表分页数据
     * @param string $where
     * @param int $limit
     * @param string $order
     * @param string $field
     * @param string $whereOr
     * @return object
     */
    public function getLists($where = '', $limit = 1, $order = '', $field = '', $whereOr = '')
    {
        $query = $this->dataQuery($where, $field, $order, $whereOr);
        // 分页数据处理
        $count = $query->count();
        $data = $query->paginate($limit);
        $page = $data->render('paginate.default');
        if (!empty($data)){
            if (is_object($data)){
                foreach ($data as &$val){
                    if (isset($val->create_time) && !empty($this->timeRules)){
                        $val->create_time = date($this->timeRules, $val->create_time);
                    }
                    if (isset($val->update_time) && !empty($this->timeRules)){
                        $val->update_time = date($this->timeRules, $val->update_time);
                    }
                }
            }
        }
        $result = new stdClass();
        $result->count = $count;
        $result->page = $page;
        $result->list = $data;

        return $result;
    }

    /**
     * API获取列表分页数据
     * @param string $where
     * @param int $limit
     * @param string $order
     * @param string $field
     * @param string $whereOr
     * @return object
     */
    public function getListPage($where = '', $limit = 1, $order = '', $field = '', $whereOr = '')
    {
        $query = $this->dataQuery($where, $field, $order, $whereOr);
        // 分页数据处理
        $count = $query->count();
        if (is_numeric($limit)){
            $query = $query->limit($limit);
        }else{
            $limit_length = explode(',', $limit);
            $limit = intval($limit_length[0]);
            $length = intval($limit_length[1]);;
            $query = $query->offset($limit)->limit($length);
        }
        $data = $query->get();
        if (!empty($data)){
            if (is_object($data)){
                foreach ($data as &$val){
                    if (isset($val->create_time) && !empty($this->timeRules)){
                        $val->create_time = date($this->timeRules, $val->create_time);
                    }
                    if (isset($val->update_time) && !empty($this->timeRules)){
                        $val->update_time = date($this->timeRules, $val->update_time);
                    }
                }
            }
        }
        $result = new stdClass();
        $result->count = $count;
        $result->list = $data;

        return $result;
    }

    // 数据查询
    protected function dataQuery($where, $field, $order, $whereOr)
    {
        $wheres = empty($where) ? $this->where : $where;
        $fields = empty($field) ? $this->fields : $field;
        $orders = empty($order) ? $this->orders : $order;
        $whereOrs = empty($whereOr) ? $this->whereOr : $whereOr;
        // 数据查询
        $query = Db::table($this->table);
        // 存在join查询
        if (!empty($this->asJoin)){
            $this_table_alias = $this->table . ' as ' . key($this->asJoin);
            $query = $query->from($this_table_alias);
            if (is_array($this->asJoin)){
                foreach ($this->asJoin as $key=>$val){
                    // 获取是否是一维数组
                    if (count($val) != count($val, 1)){
                        foreach ($val as $v){
                            $query->join($v['0'], $v['1'], $v['2'], $v['3']);
                        }
                    }else{
                        $query->join($val['0'], $val['1'], $val['2'], $val['3']);
                    }
                }
            }
        }
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->primaryKey, $wheres);
            }else{
                if (is_array($wheres)){
                    // 获取是否是一维数组
                    if (count($wheres) != count($wheres, 1)){
                        foreach ($wheres as $val){
                            $query = $query->where($val['0'], $val['1'], $val['2']);
                        }
                    }else{
                        $query = $query->where($wheres);
                    }
                }
            }
        }
        // 存在whereOr查询
        if (!empty($whereOrs)){
            $query = $query->where($whereOrs);
        }
        // 存在whereRaw查询
        if (!empty($this->whereRaw)){
            $query->whereRaw($this->whereRaw);
        }
        // 存在order排序
        if (!empty($orders)){
            $order_list = explode(',', $orders);
            if (is_array($order_list)){
                foreach ($order_list as $key=>$val){
                    $orders_by = explode(' ', $val);
                    $query = $query->orderBy($orders_by['0'], $orders_by['1']);
                }
            }
        }
        // 排除查询
        if (!empty($fields)){
            if (is_array($fields)){
                // 是否采用排除法
                $except = end($fields);
                if ($except == true){
                    // 去除不想获取的字段
                    $fields = explode(',', reset($fields));
                    $fields = array_diff($this->getTableInfo(), $fields);
                }
                $query->select($fields);
            }else{
                $fields = explode(',', $fields);
                $query->select($fields);
            }
        }
        return $query;
    }

    public function setInc($where, $field, $number = 1)
    {
        return $this->setIncDec(1, $where, $field, $number);
    }

    public function setDec($where, $field, $number = 1)
    {
        return $this->setIncDec(2, $where, $field, $number);
    }

    public function setIncDec($type, $where, $field, $number)
    {
        $wheres = empty($where) ? $this->where : $where;
        if (empty($field)) return false;
        // 数据查询
        $query = Db::table($this->table);
        // 存在where查询
        if (!empty($wheres)){
            // 主键查询
            if (is_numeric($wheres)){
                $query = $query->where($this->primaryKey, $wheres);
            }else{
                if (is_array($wheres)){
                    // 获取是否是一维数组
                    if (count($wheres) != count($wheres, 1)){
                        foreach ($wheres as $val){
                            $query = $query->where($val['0'], $val['1'], $val['2']);
                        }
                    }else{
                        $query = $query->where($wheres);
                    }
                }
            }
        }
        if ($type == 1){
            $query = $query->increment($field, $number);
        }else{
            $query = $query->decrement($field, $number);
        }
        return $query;
    }

    // 获取验证类
    public function getValidator()
    {
        // 需要去除表前缀
        $validator = str_replace(env('DB_PREFIX'), '', $this->table);
        return str_replace('_', '', ucwords($validator, '_'));
    }

    // 获取主键
    public function getPrimaryKey()
    {
        return $this->primaryKey;
    }

    // 获取错误提示信息
    public function getError()
    {
        return $this->error;
    }

    // 启动事务
    public function DbStartTrans()
    {
        $this->startTrans();
    }

    // 提交事务
    public function DbCommit()
    {
        $this->commit();
    }

    // 数据回滚
    public function DbRollback()
    {
        $this->rollback();
    }

}
